{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 简介\n",
    "\n",
    "- 项目地址：https://github.com/theskumar/python-dotenv\n",
    "\n",
    "首先看一下github上项目的介绍：\n",
    "\n",
    "　　Reads the key,value pair from .env and adds them to environment variable. \n",
    "\n",
    "　　大概意思就是在我们做项目时，我们可以把所有用到的环境变量写到.env文件里，然后以k，v的方式读取作为环境变量。\n",
    "  \n",
    "**扩展阅读**：[12-factors](https://12factor.net/zh_cn/)\n",
    "\n",
    "## 用法\n",
    "\n",
    "最简单和最常见的用法是在应用程序启动时调用`load_dotenv`，从当前目录或其父目录中的`.env`文件或指定的路径加载环境变量，然后你可以调用`os.getenv`提供的与环境相关的方法。\n",
    "\n",
    "### `.env` 文件内容写法\n",
    "\n",
    "`.env` 文件内容差不多是这样的：\n",
    "\n",
    "```ini\n",
    "# a comment that will be ignored.\n",
    "REDIS_ADDRESS=localhost:6379\n",
    "MEANING_OF_LIFE=42\n",
    "MULTILINE_VAR=\"hello\\nworld\"\n",
    "```\n",
    "\n",
    "你可以使用单词`export`作为每行的前缀，这将会使`python-dotenv` 忽略该变量，但是你可以使用 `source` 命令运行该文件。\n",
    "\n",
    "`python-dotenv` 可以用来修改 `POSIX`系统的环境变量.\n",
    "\n",
    "变量的值是下面列表中定义的第一个值:\n",
    "\n",
    "- 系统环境变量\n",
    "- `.env` 文件中定义的值\n",
    "- 默认值，如果有的话\n",
    "- 空字符串\n",
    "\n",
    "确保引用其他变量时用大括号`{}`包围，就像`${HOME}`，因为像`$HOME`这样的字符串不会被认为是变量的引用。\n",
    "\n",
    "```ini\n",
    "CONFIG_PATH=${HOME}/.config/foo\n",
    "DOMAIN=example.org\n",
    "EMAIL=admin@${DOMAIN}\n",
    "DEBUG=${DEBUG:-false}\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 项目中使用\n",
    "\n",
    "#### 安装\n",
    "\n",
    ">pip install -U python-dotenv\n",
    "\n",
    "#### 基本用法\n",
    "\n",
    "确保你的项目目录下 有 `.env` 文件\n",
    "\n",
    "```sh\n",
    ".\n",
    "├── .env\n",
    "└── settings.py\n",
    "```\n",
    "\n",
    "然后你可以在`settings.py`中添加以下代码：\n",
    "\n",
    "```py\n",
    "# settings.py\n",
    "from dotenv import load_dotenv, find_dotenv\n",
    "from pathlib import Path  # Python 3.6+ only\n",
    "\n",
    "# 一、自动搜索 .env 文件\n",
    "load_dotenv(verbose=True)\n",
    "\n",
    "\n",
    "# 二、与上面方式等价\n",
    "load_dotenv(find_dotenv(), verbose=True)\n",
    "\n",
    "# 三、或者指定 .env 文件位置\n",
    "env_path = Path('.') / '.env'\n",
    "load_dotenv(dotenv_path=env_path, verbose=True)\n",
    "```\n",
    "\n",
    "通过`load_dotenv` ，你就可以访问像访问系统环境变量一样使用`.env`文件中的变量了，比如通过 `os.genenv(key, default=None)`\n",
    "\n",
    "```py\n",
    "# settings.py\n",
    "import os\n",
    "SECRET_KEY = os.getenv(\"EMAIL\")\n",
    "DATABASE_PASSWORD = os.getenv(\"DATABASE_PASSWORD\")\n",
    "```\n",
    "\n",
    "#### 参数\n",
    "\n",
    "- `dotenv_path`: 指定`.env`文件路径，当然如果不传该参数的话（默认为`None`）也会自定调用`dotenv.find_dotenv()`去查找文件位置的，**但是你的文件名如果不是`.env`那就必须传递该参数了**\n",
    "\n",
    "- `override`： 当`.env` 文件中有变量与系统中原来的环境变量有冲突时，按照上面的取值顺序，默认使用系统变量，如果要用`.env`中的变量覆盖系统变量，可以给`load_dotenv()` 传递参数`override=True`。**此时只是临时使用了`.env` 中的变量值**\n",
    "\n",
    "- `encoding`: `load_dotenv()` 也可以传递`encoding` 参数指定文件的编码方式。\n",
    "\n",
    "#### 从流对象加载\n",
    "\n",
    "从可读的流对象中加载，记得把读指针调到要开始读取的位置。\n",
    "\n",
    "```py\n",
    ">>> from io import StringIO     # Python2: from StringIO import StringIO\n",
    ">>> from dotenv import dotenv_values\n",
    ">>> filelike = StringIO('SPAM=EGGS\\n')\n",
    ">>> filelike.seek(0)\n",
    ">>> parsed = dotenv_values(stream=filelike)\n",
    ">>> parsed['SPAM']\n",
    "'EGGS'\n",
    "```\n",
    "\n",
    "**注意**：此时返回值是个字典\n",
    "\n",
    "### Django\n",
    "\n",
    "如果你在Django中使用，请将以上代码添加到 `wsgi.py` 或者 `manage.py`.\n",
    "\n",
    "### IPython 支持\n",
    "\n",
    "1. 加载扩展\n",
    "```sh\n",
    "%load_ext dotenv\n",
    "```\n",
    "2. 加载 env文件\n",
    "```sh\n",
    "%dotenv\n",
    "```\n",
    "或者指定一个env文件\n",
    "```sh\n",
    "%dotenv relative/or/absolute/path/to/.env\n",
    "```\n",
    "3. 其他参数\n",
    "\n",
    "  - -o：即override 覆盖原有变量\n",
    "  ```sh\n",
    "  %dotenv -o\n",
    "  ```\n",
    "  - -v：输出提示信息\n",
    "  ```sh\n",
    "  %dotenv -v\n",
    "  ```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### [配置远程服务器](https://github.com/theskumar/python-dotenv#setting-config-on-remote-servers)\n",
    "\n",
    "与 [Fabric](http://www.fabfile.org) 配合使用"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {
    "height": "calc(100% - 180px)",
    "left": "10px",
    "top": "150px",
    "width": "165px"
   },
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
